#include "../logs/log.h"

enum class TimeGap
{
    SECOND,
    MINUTE,
    HUOR,
    DAY
};

// 拓展落地方式：滚动时间间隔
class rolltime_sink : public log::log_sink
{
public:
    rolltime_sink(const std::string &base_name, TimeGap gap)
    :_base_name(base_name)
    {
        switch(gap)
        {
            case TimeGap::SECOND : _gap_size = 1; break;
            case TimeGap::MINUTE : _gap_size = 60; break;
            case TimeGap::HUOR : _gap_size = 3600; break;
            case TimeGap::DAY : _gap_size = 3600 * 24; break;
            default : break;
        }

        // 创建目录
        log::tools::file::creat_directory(log::tools::file::get_path(base_name));

        if(_gap_size == 1)
            _creat_gap = log::tools::get_time::_get_time();
        else
            _creat_gap = log::tools::get_time::_get_time() % _gap_size;
    }

    void log(const char *data, size_t len)
    {
        // 初始化
        file_init();
        _ofs.write(data, len);
        if(_ofs.good() == false)
        {
            std::cout << "滚动时间间隔，日志写入失败" << endl;
            exit(-1);
        }
    }

private:
    void file_init()
    {
        size_t now_gap = log::tools::get_time::_get_time() % _gap_size;
        if(_gap_size == 1)
            now_gap = log::tools::get_time::_get_time();

        if(_ofs.is_open() == false || _creat_gap != now_gap)
        {
            _ofs.close();
            std::string file_name = creat_file_name();
            _ofs.open(file_name, std::ios::binary | std::ios::app);
            if(_ofs.is_open() == false)
            {
                std::cout << "滚动时间间隔，文件打开失败" << endl;
                exit(-1);
            }
        }
    }

    std::string creat_file_name()
    {
        std::stringstream file_name;
        time_t time = log::tools::get_time::_get_time();
        struct tm res;
        localtime_r(&time, &res);
        file_name << _base_name;
        //file_name << res.tm_year + 1900 << '-' << res.tm_mon + 1 << '-'  << res.tm_mday;
        //file_name << " ";
        file_name << res.tm_hour << '-' << res.tm_min + 1 << '-'  << res.tm_sec;
        file_name << ".log";
        return file_name.str();
    }

private:
    std::string _base_name;
    std::ofstream _ofs;
    size_t _creat_gap;
    size_t _gap_size;
};

void test_sink()
{
    std::unique_ptr<log::build_logger> b(new log::local_build_logger());
    b->build_logger_name("violet");
    b->build_formatter("[%d{%H:%M:%S}][%n][%t][%l][%f:%L]%T%m%N");
    b->build_sink<rolltime_sink>("./logfile/roll-", TimeGap::SECOND);
    log::logger::ptr l = b->build();

    size_t start = (size_t)log::tools::get_time::_get_time();
    size_t cnt = 1;
    while((size_t)log::tools::get_time::_get_time() < start + 3)
    {
        //l->fatal("测试日志");
        l->fatal("%s-%d", "测试日志", cnt++);
        usleep(1000);
    }
}

int main()
{
    test_sink();
    return 0;
}